package com.sensorfriendly.ui;

import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.speech.tts.TextToSpeech;
import android.view.Display;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.sensorfriendly.AppConstants;
import com.sensorfriendly.AppContext;
import com.sensorfriendly.R;
import com.sensorfriendly.model.Message;
import com.sensorfriendly.provider.impl.MessageDBImpl;
import com.sensorfriendly.util.ImageUtil;

/**
 * 
 * Dialog for recording audio, changing picture and changing the message content.
 *
 */
public class EditMessageDialog extends Activity implements OnClickListener, MediaPlayer.OnCompletionListener{
	
	
	private String message;
	private EditText messageEditText;
	private String category;
	private ImageView recordImage;
	private MediaRecorder mRecorder = null;
	 private MediaPlayer   mPlayer = null;
	private String audioFileName;
	private boolean playToggle;
	private boolean recordToggle;
	private TextView statusText;
	private Button previewButton;
	private String imagePath;
	private boolean update;
	private ImageView changeImageButton;
	
	private static final int GALLERY_ID = 0;
	
	
	// initialize UI components as class variables.
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.dialog_edit_message);
		Bundle extra = this.getIntent().getExtras();
		message = extra.getString(AppConstants.MESSAGE);
		category = extra.getString(AppConstants.CATEGORY);
		messageEditText = (EditText) findViewById(R.id.message_dialog_edit_name);
		if(message != null){
			messageEditText.setText(message);
			setTitle(message);
			update = true;
		}
		else{
			setTitle("Adding New Message");
			update = false;
		}
		
		((Button)findViewById(R.id.message_dialog_confirm_btn)).setOnClickListener(this);
		((Button)findViewById(R.id.message_dialog_cancel_btn)).setOnClickListener(this);
		recordImage = (ImageView) findViewById(R.id.record_image);
		recordImage.setOnClickListener(this);
		
		statusText = (TextView) findViewById(R.id.record_status);
		
		previewButton  = (Button)findViewById(R.id.message_playback_btn);
		previewButton.setOnClickListener(this);
		
		changeImageButton = (ImageView) findViewById(R.id.message_image_view);
		changeImageButton.setOnClickListener(this);
		
		
		// load and display if the message has an image.
		Message msg = (new MessageDBImpl(this)).getMessage(category, message);
		if(msg.getMessageImagePath()  != null){
			imagePath = msg.getMessageImagePath();
			setImage();
		}

	}
	
	
	// load and set the image to changeImageButton
	private void setImage(){
		Display display = getWindowManager().getDefaultDisplay();
		int screenWidth = display.getWidth()/2;
		int screenHeight = display.getHeight()/2;
		Bitmap image = ImageUtil.decodeSampledBitmapFromPath(imagePath, screenWidth, screenHeight);
		changeImageButton.setImageBitmap(image);	
	}
	
	
	
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		
		//commiting all changes when confirm is clicked and kill the activity.
		case R.id.message_dialog_confirm_btn:
			AppContext app = (AppContext) this.getApplication();
			String value = messageEditText.getText().toString();
			if(value != null && value.length()>0){
				Message msg = new Message();
				msg.setAudioFile(audioFileName);
				msg.setMessageContent(value);
				msg.setMessageImagePath(imagePath);
				msg.setScenarioName(category);
				if(update){
					app.editMessage(message, msg);
				}
				else{
					app.addNewMessage(msg);
				}
				this.finish();
				
			}
			else{
				Toast.makeText(this, "Please enter a valid name", Toast.LENGTH_LONG).show();
			}
			
			break;
		
		// kill the activiy without committing any changes
		case R.id.message_dialog_cancel_btn:
			this.finish();
			break;
		
		//start recording
		case R.id.record_image:
			if(recordToggle){
				if (audioFileName == null) {
					String messageValue = messageEditText.getText().toString();
					if (messageValue == null || messageValue.length() <= 0) {
						Toast.makeText(
								this,
								"Must enter the content of the message before recording",
								Toast.LENGTH_LONG).show();
					} else {
						message = messageValue;
					}
					
					// create the file name that the audio will be saved to.
					if (message != null) {						
						audioFileName = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/"+AppConstants.APP_EXT_FOLDER+"/"+AppConstants.MESSAGE_AUDIO_FOLDER;
						audioFileName += "/" + category.replaceAll(" ", "_");
						String tempName = message.replaceAll(",", "");
						tempName = tempName.replaceAll("\\.", "");
						tempName = tempName.replaceAll("\\?", "");
						audioFileName += "_"+tempName.replaceAll(" ", "_") + ".3gp";
					}
				}
			}
			onRecord();
			
			break;
		
		// play the audio associated with this message
		case R.id.message_playback_btn:
			onPlay();
			break;
		
		// launch the native gallery app for user to select image.
		case R.id.message_image_view:
			Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
			photoPickerIntent.setType("image/*");
			startActivityForResult(photoPickerIntent, GALLERY_ID);
			break;
		}
	
	}
	
	public void onResume(){
		super.onResume();
		playToggle = true;
		recordToggle = true;
	}
	
	
	// change recording states
    private void onRecord() {
        if (recordToggle) {
            startRecording();
            recordImage.setImageResource(R.drawable.recording_on);
            statusText.setText("Recording... \n Touch again when finish recording"); 
        } else {
            stopRecording();
            recordImage.setImageResource(R.drawable.recording_off);
            statusText.setText("Touch on the microphone to start recording" );
        }
    }
    
    
    // start recording hardware.
    private void startRecording() {
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setOutputFile(audioFileName);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        try {
            mRecorder.prepare();
        } catch (IOException e) {
        	e.printStackTrace();
        }

        mRecorder.start();
        recordToggle = false;
    }

    private void stopRecording() {
        mRecorder.stop();
        mRecorder.release();
        mRecorder = null;
        recordToggle = true;
    }
    
    private void onPlay() {
        if (playToggle) {
            startPlaying();
        } else {
            stopPlaying();
        }
    }
    
    
    private void startPlaying() {
        mPlayer = new MediaPlayer();
        mPlayer.setOnCompletionListener(this);
		if (audioFileName != null) {
			try {
				mPlayer.setDataSource(audioFileName);
				mPlayer.prepare();
				mPlayer.start();
				previewButton.setCompoundDrawablesWithIntrinsicBounds(0, android.R.drawable.ic_media_pause,0, 0);
				previewButton.setText("Stop");
				playToggle = false;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
    }

    private void stopPlaying() {
        mPlayer.release();
        mPlayer = null;
        previewButton.setCompoundDrawablesWithIntrinsicBounds(0, android.R.drawable.ic_media_play,0, 0);
		previewButton.setText("Play");
		playToggle = true;
    }
    
    
    
    @Override
    public void onPause() {
        super.onPause();
        if (mRecorder != null) {
            mRecorder.release();
            mRecorder = null;
        }
        if (mPlayer != null) {
            mPlayer.release();
            mPlayer = null;
        }
    }
    
    
    // update playing state when audio is done.
	@Override
	public void onCompletion(MediaPlayer mp) {
		stopPlaying();
	}
	
	
	/**
	 * getting the path of the image that user picked.
	 */
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		switch (requestCode) {
		case GALLERY_ID:
			if (resultCode == RESULT_OK) {
				Uri selectedImage = data.getData();
				imagePath = getPath(selectedImage);
				setImage();
			}
			break;
		}
	}
	
	/**
	 * getting file absolute path based media Uri.
	 * @param uri
	 * @return
	 */
	public String getPath(Uri uri) {
	    String selectedImagePath;
	    String[] projection = { MediaStore.Images.Media.DATA };
	    Cursor cursor = managedQuery(uri, projection, null, null, null);
	    if(cursor != null){
	        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
	        cursor.moveToFirst();
	        selectedImagePath = cursor.getString(column_index);
	    }else{
	        selectedImagePath = null;
	    }

	    if(selectedImagePath == null){
	        selectedImagePath = uri.getPath();
	    }
	    return selectedImagePath;
	}
}
